From d69fe482f95c4c3a97fcab78ab8f69a79d437b50 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 24 Dec 2009 09:06:12 +0000 Subject: [PATCH] x86/mm: early put_page when XENMEM_add_to_physmap(XENMAPSPACE_gmfn) When using a stub domain, xen massively complains as follows: (XEN) sh error: sh_remove_all_mappings(): can't find all mappings of mfn be= 3c5: c=3D8000000000000004 t=3D00000000 (XEN) sh error: sh_remove_all_mappings(): can't find all mappings of mfn be= 3c4: c=3D8000000000000004 t=3D00000000 ... This comes from the XENMEM_add_to_physmap hypercall from hvmloader. The guest_physmap_remove_page function calls sh_remove_all_mappings() which checks reference count of the page. Then, calling guest_physmap_remove_page after temporarily get_page is obviously wrong. And early put_page is harmless here since domain_lock is acquired. Also, the restore program seems not to complain extra mappings long before. Instead, the stub domain does. Thus the comment in sh_remove_all_mappings() is rewritten. Signed-off-by: Kouya Shimura --- xen/arch/x86/mm.c | 6 +++--- xen/arch/x86/mm/shadow/common.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 9eec698ae4..b9d5d49d22 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4304,6 +4304,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) domain_lock(d); + if ( page ) + put_page(page); + /* Remove previously mapped page if it was present. */ prev_mfn = gmfn_to_mfn(d, xatp.gpfn); if ( mfn_valid(prev_mfn) ) @@ -4327,9 +4330,6 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) domain_unlock(d); - if ( page ) - put_page(page); - rcu_unlock_domain(d); return rc; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 434d567536..4c0d084902 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -2606,7 +2606,7 @@ int sh_remove_all_mappings(struct vcpu *v, mfn_t gmfn) { /* Don't complain if we're in HVM and there are some extra mappings: * The qemu helper process has an untyped mapping of this dom's RAM - * and the HVM restore program takes another. */ + * and the stub domain takes another. */ if ( !(shadow_mode_external(v->domain) && (page->count_info & PGC_count_mask) <= 3 && (page->u.inuse.type_info & PGT_count_mask) == 0) ) -- 2.30.2